#!/usr/bin/env python
# $Id: test2-3.py 16f2bd2b4e2c 2012/12/15 22:47:51 pgurumur $
# Copyright (c) 2012 Prabhu Gurumurthy <pgurumur@gmail.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#

__version__  = "$Revision: 16f2bd2b4e2c $"
__author__   = "$Author: pgurumur $"
__modified__ = "$Date: 2012-12-15 22:47:51Z $"

import os
import struct

def checksum(source_string):
   # I'm not too confident that this is right but testing seems to
   # suggest that it gives the same answers as in_cksum in ping.c.
   sum = 0
   count_to = (len(source_string) / 2) * 2
   count = 0
   while count < count_to:
      this_val = ord(source_string[count + 1])*256+ord(source_string[count])
      sum = sum + this_val
      sum = sum & 0xffffffff # Necessary?
      print(this_val, sum)
      count = count + 2

   if count_to < len(source_string):
      sum = sum + ord(source_string[len(source_string) - 1])
      sum = sum & 0xffffffff # Necessary?

   sum = (sum >> 16) + (sum & 0xffff)
   sum = sum + (sum >> 16)
   answer = ~sum
   answer = answer & 0xffff
   # Swap bytes. Bugger me if I know why.
   answer = answer >> 8 | (answer << 8 & 0xff00)
   return answer

def checksum1(source):
   nleft = len(source)
   accum = 0

   flag = True
   count = 0
   while flag:
      try:
         accum += ord(source[count + 1])
         count += 2
         if count > nleft:
            flag = False
      except IndexError:
         flag = False

   count = nleft - count
   accum = (accum >> 16) + (accum & 0xFFFF)
   accum += (accum >> 16)
   accum = ~accum
   accum = accum & 0xFFFF
   return accum >> 8 | (accum << 8 & 0xFF00)

if __name__ == "__main__":
   ident = os.getpid() & 0xFFFF
   header = struct.pack('>bbHHh', 8, 0, 0, ident, 1)
   data = 192 * 'Q'

   # Calculate the checksum on the data and the dummy header.
   my_checksum = checksum1(header + data)
   print(my_checksum)
